home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 March
/
EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso
/
earcd
/
util2
/
dmouse.lha
/
DMouse
/
dlineart.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-07
|
31KB
|
1,695 lines
#define VERSION "1.4gmd "
/***************************************************************
*
* DLineArt.c
*
* DMouse screen blanker for use with DMouse V1.20
*
* read the docs file for installation procedures.
*
* Is your computer BORED? If so, then you need...
*
* DLineArt, by Steve -Raz- Berry with help
* from Matt Dillon.
*
*
**************************************************************/
// Hacked by Gary Duncan (GMD)
/* *INDENT-OFF* */
#if 0
Functions:-
main
LineArt
InitScrStructures
screenoff
screenon
do_text
do_ellipse
do_box
checkbounce_start
checkbounce_end
get_rand_point
get_rand_dir
get_rand_scale
do_spline
openlibs
closelibs
my_ran
hexit
get_flags
pause
open_timer
time_diff
ChangeColour
mouse_off
mouse_on
Midpoint
DrawBezierArc
usage
fatal_err
#endif
/* *INDENT-ON* */
#include <stdlib.h>
#include <stdio.h>
#include <exec/types.h>
#include <ctype.h>
#include <fcntl.h>
#include <string.h>
#include <exec/memory.h>
#include <intuition/preferences.h>
#include <intuition/screens.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <dos/dos.h>
#include <exec/lists.h>
#include <exec/nodes.h>
#include <time.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <devices/timer.h>
#include <clib/timer_protos.h>
#include <graphics/text.h> /*GMD */
__far extern struct Custom custom;
typedef struct real_point
{
LONG x;
LONG y;
}
LONG_POINT;
typedef enum
{
COL_RGB, COL_RANDOM
}
MY_COL;
#include "dmouse.h"
#include "Proto/dlineart_protos.h"
/*
* port name (Dmouse -> Dlineart IPC)
*/
#define DLINEART_PORT "Dlineart-DMHandler"
/*
* port name (DlineArt Internal timer - GMD)
*/
#define DLINEART_TIMER "Dlineart-Timer"
/*
* prog name
*/
#define DLINEART "dlineart"
#define MAXELLIPSE 75
#define MINBOUND 20
#define BOUNDX MAXX-MINBOUND
#define BOUNDY MAXY-MINBOUND
/*
* defaults for starting Dlineart
*/
#define DL_PAT_TIME (30*1000)
#define DL_CHG_SPD (2*1000)
#define Z_FACTOR (5 * 1000)
#define DL_STR "BOING!"
/*
* flag bits
*/
#define F_FLAG 0x20 /* must be last */
#define F_TEXTSTR 0x10
#define F_SPLINES 0x8
#define F_LINES 0x4
#define F_BOXES 0x2
#define F_ELLIPSES 0x1
#define TEXT_LEN 20
typedef struct options
{
LONG flags;
LONG flags_orig;
LONG pat_count;
LONG pat_chg_time;
LONG input;
LONG z_delay;
LONG col_chg_spd;
MY_COL col_chg_mode;
LONG maxlines;
LONG trails;
char text[TEXT_LEN];
LONG debug;
char *debug2;
}
DL_OPTIONS;
static char A_vers[] = "$VER: dlineart\t" VERSION __AMIGADATE__;
static char Version[] = "dlineart\t" VERSION __DATE__;
UWORD Mouse[1 + 9 + 1]; /* must be 0 */
static DL_OPTIONS g_dl_options;
static UWORD colour_tbl[2] =
{
0x000, /* background color - black */
0x500
};
static DL_OPTIONS *dl = &g_dl_options;
static DL_OPTIONS *g_dlb = NULL;
static int MAXX;
static int MAXY;
static char *g_TStr;
static int g_TLen;
INTUITIONBASE *IntuitionBase;
LIBRARY *TimerBase = NULL;
static GFXBASE *GfxBase;
static VIEWPORT *vp;
static SCREEN *Scr;
static WINDOW *Win;
RASTPORT *rp;
static TEXTATTR Ta =
{(UBYTE *) "topaz.font", 11, 0, 0}; /*GMD */
static NEWSCREEN Ns =
{0, 0, 0, 0, 1, 255, 255, HIRES | LACE, CUSTOMSCREEN | SCREENQUIET, &Ta};
static NEWWINDOW Nw =
{0, 0, 0, 0, 2, 1, NULL, BORDERLESS | NOCAREREFRESH | BACKDROP,
NULL, NULL, NULL, NULL, NULL, 0, 0, 8000, 8000, CUSTOMSCREEN};
static LONG g_offset = 0;
static LONG g_scale1 = 2;
static LONG g_scale2 = 2;
static LONG g_Count = 0;
static int f_mask = 1;
#define DL_STR "BOING!"
typedef struct XY
{
LONG x;
LONG y;
}
XY;
typedef struct DIRECTION
{
XY start;
XY end;
}
DIRECTION;
/*
* Maximum # of lines,boxes,ellipses to draw (watch your stack!)
*/
#define ML 500
static XY point_start[ML];
static XY point_end[ML];
static DIRECTION direction;
static TIMEREQUEST *t_req;
static MSGPORT *timerport;
static ULONG e_freq;
static ECLOCKVAL ec1;
static ECLOCKVAL ec2;
static ECLOCKVAL col_ec1;
static ECLOCKVAL col_ec2;
static LONG eloop_count;
static MSGPORT *dmport;
static MSGPORT *ipport;
static char xbuf[256];
static TASK *e_task_ptr;
static TASK *n_task_ptr;
static MSGPORT *dla_port_ptr;
static BOOL is_back = FALSE;
extern __far ULONG RangeSeed;
/*
*********************************************************************
*/
main (int argc, char **argv)
{
int var;
IOREQUEST AddReq; /* for dmouse ipc */
IOREQUEST RemReq;
BOOL notdone = TRUE;
LONG mask = 0;
int mouse_flag = 0;
/*
* see if already running
*/
Forbid ();
dla_port_ptr = FindPort (DLINEART_PORT);
Permit ();
/*
* background DLineArt task exists if Dlineart-Dmouse port exists
*/
if (dla_port_ptr != NULL)
{
PROCESS *pr;
COMMANDLINEINTERFACE *cli;
pr = (PROCESS *) FindTask (NULL);
/*
* exit if this is another 'Run Dlineart..' invocation
*/
cli = (COMMANDLINEINTERFACE *) BADDR (pr->pr_CLI);
if (cli->cli_Background == DOSTRUE)
{
fatal_err ("\nDlineart already running\n");
}
/*
* get ptr to running DlineArt's parameter area from its TCB
*/
e_task_ptr = dla_port_ptr->mp_SigTask;
g_dlb = e_task_ptr->tc_UserData;
/*
* copy its option struct
*/
*dl = *g_dlb;
dl->pat_count = 0;
dl->flags = 0;
dl->flags_orig = 0;
}
else
/*
* .. it hasn't started; so find one's TCB
* and init struct
*/
{
is_back = TRUE;
n_task_ptr = FindTask (NULL);
dl = &g_dl_options;
n_task_ptr->tc_UserData = dl;
/*
* init struct with some defaults
*/
dl->flags = 0;
dl->flags_orig = 0;
dl->pat_count = 0;
dl->pat_chg_time = DL_PAT_TIME;
dl->input = 3;
dl->z_delay = 2 * Z_FACTOR;
dl->col_chg_spd = DL_CHG_SPD;
dl->col_chg_mode = COL_RGB;
dl->maxlines = 20;
dl->trails = 1;
strcpy (dl->text, DL_STR);
}
/*
*** scan input params
*/
while (--argc >= 1)
{
LONG temp;
char *ptr = argv[argc];
if (*ptr++ == '-')
{
switch (*ptr++)
{
case 'b':
++dl->pat_count;
dl->flags_orig |= F_BOXES;
dl->flags = F_BOXES;
break;
#if 0
case 'c':
if (*ptr && (*ptr == 'R'))
{
dl->col_chg_mode = COL_RANDOM;
}
else
{
dl->col_chg_mode = COL_RGB;
}
break;
#endif
case 'e':
++dl->pat_count;
dl->flags_orig |= F_ELLIPSES;
dl->flags = F_ELLIPSES;
break;
case 'h': /* Help ; GMD */
usage ();
hexit ();
case 'i': /* new ; GMD */
temp = atoi (ptr);
if (temp < 1)
temp = 1;
else if (temp > 9)
temp = 9;
dl->input = temp;
break;
case 'p': /* pattern change */
temp = atoi (ptr);
if (temp < 1)
temp = 10;
dl->pat_chg_time = temp * 1000;
break;
case 'l':
dl->maxlines = atoi (ptr);
if (dl->maxlines > ML)
{
dl->maxlines = ML;
}
else if (dl->maxlines < 1)
{
dl->maxlines = 1;
}
break;
case 'q': /* new (quit); GMD */
if (e_task_ptr == NULL)
{
printf ("%s", DLINEART " not running\n");
}
else
{
printf ("%s",
DLINEART " active; sending quit signal ( ^C)\n");
Signal (e_task_ptr, SIGBREAKF_CTRL_C); /* stop it */
}
hexit ();
case 'T':
++dl->pat_count;
dl->flags_orig |= F_TEXTSTR;
dl->flags = F_TEXTSTR;
strncpy (dl->text, ptr, TEXT_LEN - 1);
g_TStr = dl->text;
g_TLen = strlen (g_TStr);
break;
case 'z': /* (GMD) delay factor (0-9, 5 msecs per unit) */
{
int temp = atoi (ptr);
if (temp > 9)
temp = 9; /* silent max */
dl->z_delay = temp * Z_FACTOR; /* chosen by testing */
}
break;
case 'S': /* change-colour Speed */
{
int temp = atoi (ptr);
if (temp < 1)
temp = 1;
dl->col_chg_spd = temp * 1000;
}
break;
case 's':
++dl->pat_count;
dl->flags_orig |= F_SPLINES;
dl->flags = F_SPLINES;
break;
case 't':
dl->trails = 0;
break;
case 'v': /* print params */
if (dla_port_ptr == NULL)
{
printf ("Dlineart not running\n");
hexit ();
}
v_option ();
exit (0);
default:
printf ("Error: (%s) invalid option\n", --ptr);
hexit ();
}
}
else
{
sprintf (xbuf, "Error: (%s) not an option\n", --ptr);
fatal_err (xbuf);
}
}
/*
*** END of scan input params
*/
/*
* if not background, then a param update to background dlineart
*/
if (is_back == FALSE)
{
if (dl->pat_count)
{
g_dlb->pat_count = dl->pat_count;
if (g_dlb->flags != dl->flags)
{
g_dlb->flags = dl->flags;
}
if (g_dlb->flags_orig != dl->flags_orig)
{
g_dlb->flags_orig = dl->flags_orig;
}
}
if (g_dlb->pat_chg_time != dl->pat_chg_time)
{
g_dlb->pat_chg_time = dl->pat_chg_time;
}
if (g_dlb->input != dl->input)
{
g_dlb->input = dl->input;
}
if (g_dlb->z_delay != dl->z_delay)
{
g_dlb->z_delay = dl->z_delay;
}
if (g_dlb->col_chg_spd != dl->col_chg_spd)
{
g_dlb->col_chg_spd = dl->col_chg_spd;
}
if (g_dlb->col_chg_mode != dl->col_chg_mode)
{
g_dlb->col_chg_mode = dl->col_chg_mode;
}
if (g_dlb->maxlines != dl->maxlines)
{
g_dlb->maxlines = dl->maxlines;
}
if (g_dlb->trails != dl->trails)
{
g_dlb->trails = dl->trails;
}
if (strcmp (g_dlb->text, dl->text) != 0)
{
strcpy (g_dlb->text, dl->text);
}
hexit ();
}
/*
*** create i/p port for DMouse-Handler access
*/
ipport = CreatePort (DLINEART_PORT, 0); /* ipc port */
if (ipport == NULL)
{
fatal_err ("Can't create port for DMouse access\n");
}
/*
*** come here only for 1st background invocation 'Run Dlineart ..'
* (GMD) now open Timer for use in slowing display (-z option)
*/
/*
* set up some default flags
*/
if (dl->flags == 0)
{
dl->pat_count = 3;
dl->flags = F_BOXES;
dl->flags_orig = F_SPLINES | F_BOXES | F_ELLIPSES;
}
open_timer ();
/*
*** open Libraries
*/
openlibs ();
InitScrStructures ();
for (var = 0; var < VBeamPos (); ++var)
get_rand_point ();
/*
* Init starting points
*/
point_start[0].x = get_rand_point ();
/* Initial start x,y (one endpoint) */
point_start[0].y = get_rand_point ();
point_end[0].x = get_rand_point ();
point_end[0].y = get_rand_point ();
direction.start.x = get_rand_dir ();
direction.start.y = get_rand_dir ();
direction.end.x = get_rand_dir ();
direction.end.y = get_rand_dir ();
/*
* let Dmouse-handler know I'm here ...
*/
AddReq.io_Message.mn_ReplyPort = ipport;
AddReq.io_Command = DMCMD_ADDHANDLER;
AddReq.io_Unit = (UNIT *) dl->debug2;
AddReq.io_Flags = SBF_BOTH; /* screen blanker, and mouse blanker */
Forbid ();
if (dmport = FindPort (DMOUSE_IPC))
PutMsg (dmport, &AddReq.io_Message);
Permit ();
if (dmport == NULL)
{
fatal_err ("DMouse not running or < V1.20\n");
}
mask = SIGBREAKF_CTRL_C | (1 << ipport->mp_SigBit);
/*
* infinite loop ; wait for Dmouse signals, or CTRL-C
*/
while (notdone == TRUE)
{
ULONG sig_result;
mouse_flag = 0;
/*
* if DlineArt active (Scr) , test signals else Wait
*/
if (Scr)
sig_result = SetSignal (0L, mask);
else
sig_result = Wait (mask);
/*
* if CTRL_C set loop exit flag
*/
if (sig_result & SIGBREAKF_CTRL_C)
notdone = FALSE;
/*
* if a signal from dmouse-handler, process its message
*/
if (sig_result & (1 << ipport->mp_SigBit))
{
IOREQUEST *ior;
while (ior = (IOREQUEST *) GetMsg (ipport))
{
if (ior->io_Message.mn_Node.ln_Type == NT_REPLYMSG)
{
notdone = FALSE;
continue;
}
switch (ior->io_Command)
{
case DMCMD_SCREENON:
e_freq = ReadEClock (&ec1);
col_ec1 = ec1;
screenon ();
break;
case DMCMD_SCREENOFF:
screenoff ();
break;
case DMCMD_MOUSEOFF:
mouse_off ();
break;
case DMCMD_MOUSEON:
mouse_on ();
break;
case DMCMD_PLEASEREMOVE:
notdone = FALSE;
break;
}
ReplyMsg (&ior->io_Message);
}
}
if (Win)
{
/*
* Now go and draw something ...
*/
if (dl->z_delay)
{
pause (dl->z_delay); /* slow down maybe (-z option) */
}
/*
* fancy screen drawing done here...
*/
LineArt ();
}
}
/*
* dlineart killed (^C); clean up and exit
*/
screenon ();
mouse_on ();
RemReq.io_Message.mn_ReplyPort = ipport;
RemReq.io_Command = DMCMD_REMHANDLER;
RemReq.io_Unit = (UNIT *) dl->debug2;
PutMsg (dmport, &RemReq.io_Message);
{
IOREQUEST *ior = NULL;
while (ior != &AddReq)
{
WaitPort (ipport);
ior = (IOREQUEST *) GetMsg (ipport);
if (ior->io_Message.mn_Node.ln_Type == NT_MESSAGE)
ReplyMsg (&ior->io_Message);
}
}
hexit ();
}
/*
*********************************************************************
*/
/*
* called from loop in main ()
*/
void
LineArt ()
{
int newoffs, tempx, tempy;
SetAPen (rp, 1L);
switch (dl->flags)
{
case F_LINES:
Move (rp, point_start[g_offset].x, point_start[g_offset].y);
Draw (rp, point_end[g_offset].x, point_end[g_offset].y);
break;
case F_ELLIPSES:
do_ellipse (g_offset);
break;
case F_BOXES:
do_box (g_offset);
break;
case F_SPLINES:
do_spline (g_offset);
break;
case F_TEXTSTR:
do_text (g_offset);
break;
}
/*
* start x,y
*/
if (checkbounce_start (g_offset))
{
tempx = direction.start.x;
tempy = direction.start.y;
if (point_start[g_offset].x <= MINBOUND)
{
direction.start.x = 1;
}
else
{
if (point_start[g_offset].x >= BOUNDX)
direction.start.x = -1;
else
direction.start.x = get_rand_dir ();
}
if (point_start[g_offset].y <= MINBOUND)
{
direction.start.y = 1;
}
else
{
if (point_start[g_offset].y >= BOUNDY)
direction.start.y = -1;
else
direction.start.y = get_rand_dir ();
}
g_scale1 = get_rand_scale ();
}
/*
* end x,y
*/
if (checkbounce2 (g_offset))
{
tempx = direction.end.x;
tempy = direction.end.y;
if (point_end[g_offset].x <= MINBOUND)
{
direction.end.x = 1;
}
else
{
if (point_end[g_offset].x >= BOUNDX)
direction.end.x = -1;
else
direction.end.x = get_rand_dir ();
}
if (point_end[g_offset].y <= MINBOUND)
{
direction.end.y = 1;
}
else
{
if (point_end[g_offset].y >= BOUNDY)
direction.end.y = -1;
else
direction.end.y = get_rand_dir ();
}
g_scale2 = get_rand_scale ();
}
/*
* now see if time to change colour
*/
++g_Count;
e_freq = ReadEClock (&col_ec2);
if (time_diff (e_freq, &col_ec1, &col_ec2) > dl->col_chg_spd)
{
col_ec1 = col_ec2;
ChangeColour (dl->col_chg_mode);
}
/*
* now see if time to change pattern
*/
e_freq = ReadEClock (&ec2);
if (time_diff (e_freq, &ec1, &ec2) > dl->pat_chg_time)
{
ec1 = ec2;
/*
* Change colour , also
*/
ChangeColour (dl->col_chg_mode);
g_Count = dl->maxlines;
if ((dl->trails == 0) || (dl->pat_count > 1))
{
g_Count = 0;
g_offset = 0;
Move (rp, 0, 0);
ClearScreen (rp);
/*
* if multiple patterns, select next
*/
if (dl->pat_count > 1)
{
int j = 32;
while (--j)
{
f_mask = f_mask << 1;
if (f_mask & F_FLAG)
f_mask = 1;
if (dl->flags_orig & f_mask)
{
dl->flags = f_mask;
break;
}
}
}
}
}
++g_offset;
if (g_offset > dl->maxlines)
g_offset = 0;
/* Erase the oldest line... (or ellipse) */
if (g_Count > (dl->maxlines - 1))
{
newoffs = (g_offset == dl->maxlines) ? 0 : g_offset + dl->trails;
SetAPen (rp, 0L);
switch (dl->flags)
{
case F_LINES:
Move (rp, point_start[newoffs].x, point_start[newoffs].y);
Draw (rp, point_end[newoffs].x, point_end[newoffs].y);
break;
case F_ELLIPSES:
do_ellipse (newoffs);
break;
case F_BOXES:
do_box (newoffs);
break;
case F_SPLINES:
do_spline (newoffs);
break;
case F_TEXTSTR:
do_text (newoffs);
break;
}
SetAPen (rp, 1L);
}
/* Calculate the next point */
newoffs = (g_offset > 0) ? g_offset - 1 : dl->maxlines;
point_start[g_offset].x = (g_scale1 * direction.start.x) + point_start[newoffs].x;
point_start[g_offset].y = (g_scale1 * direction.start.y) + point_start[newoffs].y;
if (dl->flags != F_TEXTSTR)
{
point_end[g_offset].x = (g_scale2 * direction.end.x) + point_end[newoffs].x;
point_end[g_offset].y = (g_scale2 * direction.end.y) + point_end[newoffs].y;
}
else
{
point_end[g_offset].x = point_start[g_offset].x + TextLength (rp, g_TStr, g_TLen);
point_end[g_offset].y = point_start[g_offset].y;
}
}
/*
*********************************************************************
*/
void
InitScrStructures ()
{
SCREEN scr;
if (GetScreenData (&scr, sizeof (scr), WBENCHSCREEN, NULL))
{
if (scr.ViewPort.Modes & HIRES)
MAXX = scr.Width;
else
MAXX = scr.Width * 2;
if (scr.ViewPort.Modes & LACE)
MAXY = scr.Height;
else
MAXY = scr.Height * 2;
}
else
{
MAXX = 640;
MAXY = 200;
}
Ns.Width = MAXX;
Nw.Width = MAXX;
Ns.Height = MAXY;
Nw.Height = MAXY;
}
/*
*********************************************************************
*/
void
screenoff ()
{
if (Scr)
ScreenToFront (Scr);
else if (Scr = OpenScreen (&Ns))
{
Nw.Screen = Scr;
if (Win = OpenWindow (&Nw))
{
vp = &Scr->ViewPort;
rp = Win->RPort;
LoadRGB4 (vp, colour_tbl, 2L);
}
ShowTitle (Scr, FALSE);
}
}
/*
*********************************************************************
*/
void
screenon ()
{
if (Win)
CloseWindow (Win);
if (Scr)
CloseScreen (Scr);
Win = NULL;
Scr = NULL;
vp = NULL;
rp = NULL;
}
/*
*********************************************************************
*/
void
do_text (int g_offset)
{
SHORT x, y;
x = (Scr->Width - TextLength (rp, g_TStr, g_TLen) - 20);
y = (Scr->Height - Scr->RastPort.TxHeight - Scr->RastPort.TxBaseline - 8);
if (x < 0 || y < 0)
return;
x = (x < point_start[g_offset].x) ? x : point_start[g_offset].x;
y = (y < point_start[g_offset].y) ? y : point_start[g_offset].y;
Move (rp, x, y);
Text (rp, g_TStr, g_TLen);
}
/*
*********************************************************************
*/
void
do_ellipse (int offs)
{
int tempx, tempy;
tempx = (point_end[offs].x > point_start[offs].x) ?
point_end[offs].x - point_start[offs].x :
point_start[offs].x - point_end[offs].x;
tempy = (point_end[offs].y > point_start[offs].y) ?
point_end[offs].y - point_start[offs].y :
point_start[offs].y - point_end[offs].y;
tempx = (tempx > point_start[offs].x) ? point_start[offs].x :
((tempx + point_start[offs].x) > BOUNDX) ? BOUNDX - point_start[offs].x :
tempx;
tempy = (tempy > point_start[offs].y) ? point_start[offs].y :
((tempy + point_start[offs].y) > BOUNDY) ? BOUNDY - point_start[offs].y :
tempy;
tempx = (tempx > MAXELLIPSE) ? MAXELLIPSE : tempx;
tempy = (tempy > MAXELLIPSE) ? MAXELLIPSE : tempy;
if ((tempx > 0) && (tempy > 0))
DrawEllipse (rp, point_start[offs].x, point_start[offs].y, tempx, tempy);
}
/*
*********************************************************************
*/
void
do_box (int K)
{
int tempx, tempy;
Move (rp, point_start[K].x, point_start[K].y);
Draw (rp, point_end[K].x, point_end[K].y);
tempx = MAXX - point_start[K].x;
tempy = MAXY - point_start[K].y;
if ((tempx >= 0) && (tempy >= 0))
Draw (rp, tempx, tempy);
tempx = MAXX - point_end[K].x;
tempy = MAXY - point_end[K].y;
if ((tempx >= 0) || (tempy >= 0))
Draw (rp, tempx, tempy);
Draw (rp, point_start[K].x, point_start[K].y);
}
/*
*********************************************************************
*/
LONG
checkbounce_start (int index)
{
return (point_start[index].x >= BOUNDX) | (point_start[index].y >= BOUNDY) |
(point_start[index].x <= MINBOUND) | (point_start[index].y <= MINBOUND);
}
/*
*********************************************************************
*/
LONG
checkbounce2 (int index)
{
return (point_end[index].x >= BOUNDX) | (point_end[index].y >= BOUNDY) |
(point_end[index].x <= MINBOUND) | (point_end[index].y <= MINBOUND);
}
/*
*********************************************************************
*/
int
get_rand_point ()
{
SHORT temp;
temp = my_ran ();
if (temp < 0)
temp = temp * -1;
temp = temp / 319 + 19;
return (temp > MAXY) ? MAXY : temp;
}
/*
*********************************************************************
*/
int
get_rand_dir ()
{
SHORT num;
num = my_ran ();
return (num < -5000) ? -1 : (num > 5000) ? 1 : 0;
}
/*
*********************************************************************
*/
int
get_rand_scale ()
{
SHORT temp;
temp = my_ran ();
if (temp < 0)
temp = temp * -1;
temp = temp / 6560 + (SHORT) dl->input;
return (temp > 17) ? 17 : temp;
}
/*
*********************************************************************
*/
void
do_spline (int index)
{
int index1;
LONG_POINT p1, p2, p3, p4;
if (index == 0)
index1 = dl->maxlines;
else
index1 = index - 1;
Move (rp, (LONG) (point_start[index].x), (LONG) (point_start[index].y));
p1.x = point_start[index].x;
p1.y = point_start[index].y;
p2.x = point_end[index].x;
p2.y = point_end[index].y;
p3.x = point_start[index1].x;
p3.y = point_start[index1].y;
p4.x = point_end[index1].x;
p4.y = point_end[index1].y;
DrawBezierArc (Win, &p1, &p2, &p3, &p4);
}
/*
*********************************************************************
*/
int
openlibs ()
{
if ((IntuitionBase =
(INTUITIONBASE *) OpenLibrary ("intuition.library", 37)) == NULL)
{
fatal_err ("\nCan't open intuition.library\n");
}
if ((GfxBase = (GFXBASE *) OpenLibrary ("graphics.library", 37)) == NULL)
{
fatal_err ("\nCan't open graphics.library\n");
}
return 1;
}
/*
*********************************************************************
*/
void
closelibs ()
{
if (IntuitionBase)
CloseLibrary ((LIBRARY *) IntuitionBase);
if (GfxBase)
CloseLibrary ((LIBRARY *) GfxBase);
}
/*
*********************************************************************
*/
USHORT
my_ran ()
{
/*
* was myrand()
*/
static long rv = 34987;
rv = (rv * 13 + 1) ^ (rv >> 13);
return ((USHORT) rv);
}
/*
*********************************************************************
*/
void
hexit ()
{
if (ipport)
DeletePort (ipport);
if (t_req)
DeleteExtIO ((IOREQUEST *) t_req);
if (timerport)
DeletePort (timerport);
closelibs ();
exit (0);
}
/*
*********************************************************************
*/
char *
get_flags (LONG flags)
{
static char buf[50];
buf[0] = '\0';
if (flags & F_TEXTSTR)
{
strcat (buf, "TEXTSTR ");
}
if (flags & F_SPLINES)
{
strcat (buf, "SPLINES ");
}
if (flags & F_LINES)
{
strcat (buf, "LINES ");
}
if (flags & F_BOXES)
{
strcat (buf, "BOXES ");
}
if (flags & F_ELLIPSES)
{
strcat (buf, "ELLIPSES ");
}
return buf;
}
/*
*********************************************************************
*/
void
pause (LONG val)
{
t_req->tr_node.io_Command = TR_ADDREQUEST;
t_req->tr_time.tv_secs = 0;
t_req->tr_time.tv_micro = val;
DoIO ((IOREQUEST *) t_req);
}
/*
*********************************************************************
*/
void
open_timer ()
{
if ((timerport = CreatePort (DLINEART_TIMER, 0)) == NULL)
{
fatal_err ("Timer Port create failure\n");
}
if ((t_req = (TIMEREQUEST *) CreateExtIO ((MSGPORT *) timerport,
sizeof (TIMEREQUEST))) == NULL)
{
fatal_err ("Couldn't CreateExtIO in open_timer()\n");
}
if (OpenDevice (TIMERNAME, UNIT_MICROHZ, (IOREQUEST *) t_req, 0L) != 0)
{
fatal_err ("Couldn't open MicroHz Timer\n");
}
TimerBase = (LIBRARY *) t_req->tr_node.io_Device;
}
/*
*********************************************************************
*/
/*
* returns number of msecs between first ECLOCK and second ECLOCK
*
* (GMD)
*
* - not precise, but a hack ; divides (shifts) by 1024 not 1000.
*
*/
LONG
time_diff (ULONG e_freq, ECLOCKVAL * e_val1, ECLOCKVAL * e_val2)
{
LONG temp, msecs;
if (e_val2->ev_lo > e_val1->ev_lo)
{
temp = e_val2->ev_lo - e_val1->ev_lo;
}
else
{
temp = e_val1->ev_lo - e_val2->ev_lo;
}
/*
* convert to msecs
*/
e_freq = e_freq >> 10; /* roughly , /1024 */
msecs = temp / e_freq;
return msecs;
}
/*
*********************************************************************
*/
static int c3;
void
ChangeColour (MY_COL flag)
{
UWORD temp = RangeRand (4096); /*GMD */
static int comb[] =
{
0x00F,
0xF0F,
0x0FF,
0x8F0,
0xF00,
0x0F8,
0xF80,
0x88F,
0xF88,
0x08F,
0xF08,
0x0F0,
0x8F8,
0xF0F,
0x0F3,
0x80F,
};
if (flag == COL_RGB)
{
++c3;
temp = comb[c3 % 16];
}
colour_tbl[1] = temp & 0xFFF;
LoadRGB4 (vp, colour_tbl, 2L);
}
/*
*********************************************************************
*/
void
mouse_off ()
{
WaitTOF ();
OFF_SPRITE;
custom.spr[0].dataa = 0; /* sprite0 DMA */
custom.spr[0].datab = 0; /* data register */
#if 0
SetPointer (Win, Mouse, 16, 16, 0, 0);
#endif
}
/*
*********************************************************************
*/
void
mouse_on ()
{
ON_SPRITE;
}
/*
*********************************************************************
*/
/*
* The following code taken from Fish Disk 97 , with a small modification
* (reals -> longs, for speed) ; GMD
*/
/*<<<<<<<<<<<<<<<<<<<<<<<< code extract follows >>>>>>>>>>>>>>>>>>>>> */
/* The routines in this file are copyright (c) 1987 by Helene (Lee) Taran.
* Permission is granted for use and free distribution as long as the
* original author's name is included with the code.
*/
/*
* Midpoint: returns the midpoint of the line through <p0> and <p1>
*/
void
Midpoint (m, p0, p1)
LONG_POINT *m, *p0, *p1;
{
m->x = (p0->x + p1->x) / 2;
m->y = (p0->y + p1->y) / 2;
}
/* DrawBezierArc: draws a bezier arc between the 4 given points by
* recursively subdividing the curve until each segment is close
* enough to be rendered as a line.
* Assumes that your window <w> has been initialized and opened and that
* in addition to the intuition library, the graphics library is open
*/
#define CLOSENESS 8
void
DrawBezierArc (w, p000, p001, p011, p111)
struct Window *w; /* draw the arc in this window */
LONG_POINT *p000, *p001, *p011, *p111; /* bezier control points */
{
LONG_POINT p00t, p0t1, pt11, p0tt, ptt1, pttt;
LONG delta1 = (p001->x * p011->y - p001->y * p011->x) -
(p000->x * p011->y - p000->y * p011->x) +
(p000->x * p001->y - p000->y * p001->x);
LONG delta2 = (p111->x * p011->y - p111->y * p011->x) -
(p000->x * p011->y - p000->y * p011->x) +
(p000->x * p111->y - p000->y * p111->x);
if ((delta1 + delta2) <= CLOSENESS)
{ /* so close, just draw a line */
Move (w->RPort, (long) p000->x, (long) p000->y);
Draw (w->RPort, (long) p111->x, (long) p111->y);
}
else
{ /* divide the arc into two smaller bezier arcs */
Midpoint (&p00t, p000, p001);
Midpoint (&p0t1, p001, p011);
Midpoint (&pt11, p011, p111);
Midpoint (&p0tt, &p00t, &p0t1);
Midpoint (&ptt1, &p0t1, &pt11);
Midpoint (&pttt, &p0tt, &ptt1);
DrawBezierArc (w, p000, &p00t, &p0tt, &pttt);
DrawBezierArc (w, &pttt, &ptt1, &pt11, p111);
}
}
/*<<<<<<<<<<<<<<<<<<<<<< end ; code extract follows >>>>>>>>>>>>>>>>>>>>> */
/*--*/
/*
*********************************************************************
*/
void
usage (void)
{
int j = 0;
char *ptr;
static char *ray[] =
/* *INDENT-OFF* */
{
"dlineart options",
"",
" -q Stop dlineart if activated",
" -v Print parameters/defaults of a running dlineart",
" -b Draw boxes [default = yes]",
" -e Draw ellipses [default = yes]",
" -s Draw splines [default = yes]",
" -SX Change colour every X secs [default = 1]",
" -pX Change pattern every X secs [default = 5]",
" -lX Draw X lines before erasing the last one.",
" -zX Slow display; X=0 is fastest, X=9 slowest",
" -t This leaves a trail (one out of every 'l' lines)",
" -T\"string\" write <string> (default BOING)",
" -h Help, this message",
" -iX X is an integer between 1 and 9 that will change",
" the minimum distance between successive endpoints for",
" each line drawn. High numbers are faster.",
"",
" To invoke dlineart, type \"Run dlineart >nil: <nil: options...\"",
NULL
};
/* *INDENT-ON* */
/*
* Version
*/
printf ("%s\n\n", Version);
while (ptr = ray[j++])
printf ("%s\n", ptr);
}
/*
*********************************************************************
*/
void
fatal_err (char *ptr)
{
static LONG DBFh;
char f_buf[256];
DBFh = Open ("CON:0/0/500/100/DLineArt-FATAL", 1006);
if (DBFh == 0)
hexit ();
Write (DBFh, ptr, strlen (ptr));
sprintf (f_buf, "\nHit RET to exit\n");
Write (DBFh, f_buf, strlen (f_buf));
if (FGetC (DBFh))
Close (DBFh);
hexit ();
}
/*
*********************************************************************
*/
void
v_option ()
{
printf ("%s\n\n", Version);
dl = g_dlb;
printf ("(-b, -e, -s) = %s\n", get_flags (dl->flags_orig));
if (dl->flags_orig & F_TEXTSTR)
{
if (strlen (dl->text))
printf ("(-T) text str = %s\n", dl->text);
}
printf ("(-i) input = %d\n", dl->input);
printf ("(-z) speed = %d [range : 0 - 9]\n",
dl->z_delay / Z_FACTOR);
printf ("(-S) colour = change every %d secs\n",
dl->col_chg_spd / 1000);
printf ("(-p) pattern = change every %d secs\n",
dl->pat_chg_time / 1000);
printf ("(-l) maxlines = %d\n", dl->maxlines);
printf ("(-t) trails = %d\n", dl->trails);
}
/* */